/*
 *  Created on: Apr 17, 2009
 *      Author: Ramesh Rajaby
 */

#include "Shared.h"


string CompilerOptions::NOT_COMPILED_EXTENSION = ".idea";
string CompilerOptions::COMPILED_EXTENSION = ".score";

string LanguageKeywords::CLASS = "class";
string LanguageKeywords::END_SCOPE = "end";
string LanguageKeywords::LOAD_EXTERNAL_CLASS = "load";
string LanguageKeywords::MEMBERS = "members:";
string LanguageKeywords::METHODS = "methods:";
string LanguageKeywords::NEW = "new";
string LanguageKeywords::VARIABLE_TYPE = "Variable";

string LanguageKeywords::RESERVED_VAR = "$temp";
string LanguageKeywords::SPECIAL_ASSIGNMENT = "$spec_ass";
string LanguageKeywords::SL_COMMENT = "//";

string LanguageKeywords::PRIVATE = "private";
string LanguageKeywords::PUBLIC = "public";

int BytecodeKeywords::NULL_ = 0;

Size Types::SIZES[Types::PRIMITIVES_NUMBER+1] = {0, 4, 8, 4, 8, 1, 4};
string Types::KEYWORDS[Types::PRIMITIVES_NUMBER+1] = {"void", "int", "long", "float", "double", "char", "String"};
string Types::POINTER_KEYWORD = "ptr";

string LowLevelInstructions::ASSIGN = "ass";
string LowLevelInstructions::ADD = "add";
string LowLevelInstructions::ADD3 = "add3";
string LowLevelInstructions::SUB = "sub";
string LowLevelInstructions::SUB3 = "sub3";
string LowLevelInstructions::MUL = "mul";
string LowLevelInstructions::MUL3 = "mul3";
string LowLevelInstructions::DIV = "div";
string LowLevelInstructions::DIV3 = "div3";
string LowLevelInstructions::MOD = "mod";
string LowLevelInstructions::MOD3 = "mod3";

string LowLevelInstructions::LESS = "less";
string LowLevelInstructions::LESSEQ = "lesseq";
string LowLevelInstructions::EQUAL = "eq";
string LowLevelInstructions::UNEQUAL = "uneq";

string LowLevelInstructions::JABS = "jabs";
string LowLevelInstructions::JREL = "jrel";

string LowLevelInstructions::JLESS = "jless";
string LowLevelInstructions::JLESSEQ = "jlesseq";
string LowLevelInstructions::JEQUAL = "jeq";
string LowLevelInstructions::JUNEQUAL = "juneq";

string LowLevelInstructions::SCAN = "scan";
string LowLevelInstructions::PRINT = "print";
string LowLevelInstructions::PRINTLN = "println";

string LowLevelInstructions::ASSIGN_HEAPTOSTACK = "ass_heaptostack";
string LowLevelInstructions::ADD_HEAPTOSTACK = "add_heaptostack";
string LowLevelInstructions::SUB_HEAPTOSTACK = "sub_heaptostack";
string LowLevelInstructions::MUL_HEAPTOSTACK = "mul_heaptostack";
string LowLevelInstructions::DIV_HEAPTOSTACK = "div_heaptostack";
string LowLevelInstructions::MOD_HEAPTOSTACK = "mod_heaptostack";

string LowLevelInstructions::ASSIGN_STACKTOHEAP = "ass_stacktoheap";
string LowLevelInstructions::ADD_STACKTOHEAP = "add_stacktoheap";
string LowLevelInstructions::SUB_STACKTOHEAP = "sub_stacktoheap";
string LowLevelInstructions::MUL_STACKTOHEAP = "mul_stacktoheap";
string LowLevelInstructions::DIV_STACKTOHEAP = "div_stacktoheap";
string LowLevelInstructions::MOD_STACKTOHEAP = "mod_stacktoheap";


string Types::getTypeKeyword(int typeId) {
	if (typeId < Types::PRIMITIVES_NUMBER+1) {
		return KEYWORDS[typeId];
	} else {
		return POINTER_KEYWORD;
	}
}

int Types::getSize(int typeId) {
	if (typeId < Types::PRIMITIVES_NUMBER) {
		return SIZES[typeId];
	} else {
		return POINTER_SIZE;
	}
}


int Types::getConstantType(string c) {
	trim(c);
	if (c.empty()) {
		return 0;
	}

	if (c.length() >= 3 && c[0] == '\'' && c[c.length()-1] == '\'') {
		return Types::CHAR;
	}
	if (c.length() >= 2 && c[0] == '"' && c[c.length()-1] == '"') {
		return Types::STRING;
	}

	bool decimal = false;
	for (int i = 0; i < (int)c.length(); i++)
		if (c[i] == '.') {
			if (decimal)
				return 0;
			else
				decimal = true;
		}

	if (!isdigit(c[0]) && c[0] != '-') {
		return 0;
	}
	for (int i = 1; i < (int)c.length()-1; i++) {
		if (!isdigit(c[i]) && c[i] != '.') {
			return 0;
		}
	}

	if (decimal) {
		if (isdigit(c[c.length()-1])) {
			try {
				lexical_cast<float>(c);
				return Types::FLOAT;
			} catch (...) {
				return Types::DOUBLE;
			}
		} else if (c[c.length()-1] == 'd') {
			return Types::DOUBLE;
		}
	} else {
		if (isdigit(c[c.length()-1])) {
			try {
				lexical_cast<int>(c);
				return Types::INT;
			} catch (...) {
				return Types::LONG;
			}
		} else if (c[c.length()-1] == 'l') {
			return Types::LONG;
		}
	}
	return 0;
}
